#
# Okimi 2013 - V0.1b
#
# This tool only work with millimeter (beta)
#
# THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#

require 'sketchup.rb'



class	Net_Okimi_BoxJoint

# Constants
STATE_NONE								= 0
STATE_WAIT_FOR_SELECTING_FIRST_FACE		= 1
STATE_WAIT_FOR_SELECTING_FIRST_EDGE		= 2
STATE_WAIT_FOR_SELECTING_SECONDE_EDGE	= 3
STATE_WAIT_FOR_ENTERING_VALUES			= 4

DEBUG_MODE								= false



###############################################################################
#
# Events from Sketchup
#
###############################################################################


# This is the standard Ruby initialize method that is called when you create
# a new object.
def	initialize
	
	@state = STATE_NONE
	
	@selectedFace = nil
	@vertices = nil
	@firstEdge = nil
	@secondeEdge = nil
	@dialog = nil
	@faceLenght = 0
	@jointNumber = ''
	@jointHeight = 0
	@oppositeEdge = false

end


# The activate method is called by SketchUp when the tool is first selected.
# it is a good place to put most of your initialization
def activate
	
	@selectedFace = nil
	@firstEdge = nil
	@secondeEdge = nil
	@vertices = nil
	@dialog = nil
	@faceLenght = 0
	@jointNumber = ''
	@jointHeight = 0
	@oppositeEdge = false



	# Clear the selection
	Sketchup.active_model.selection.clear

	# Open the dialog box
	@dialog = UI::WebDialog.new( "BOX JOINT", true, "", 410, 600, 600, 0, true )
	@dialog.set_on_close { onDialogClose }
	@dialog.add_action_callback( "Validation" ) { |dialog, message|
		onValidation message
	}
	html_path = Sketchup.find_support_file "net_okimi_boxjoint\\net_okimi_boxjoint.html" ,"Plugins"
	@dialog.set_file html_path
	@dialog.show { onDialogShow }
    Sketchup.set_status_text "BOX JOINT - Select a face", SB_PROMPT

    # And wait the clic !
	@state = STATE_WAIT_FOR_SELECTING_FIRST_FACE
	
end


# The onLButtonUp method is called when the user releases the left mouse button.
def	onLButtonDown( flags, x, y, view )

	case @state
	
	when STATE_WAIT_FOR_SELECTING_FIRST_FACE

		# Wait for the fisrt selection : a face with 4 vertices
		
		# Look entitie under mouse
		pick_helper = Sketchup.active_model.active_view.pick_helper
		pick_helper.do_pick x,y
		@selectedFace = pick_helper.picked_face
		
		# Is the selected entitie is face ?
		if not (@selectedFace.is_a? Sketchup::Face)
			UI.messagebox( 'You must select only a face !')
			return
		end
		# And a face with 4 vertices ?
		@vertices = @selectedFace.vertices
		if ( @vertices.length != 4 )
			UI.messagebox( 'You must select a face with 4 vertices !')
			return
		end
		
		# The first selection is OK

		if DEBUG_MODE
			# Show edges order
			Sketchup.active_model.active_entities.add_text "0", @vertices[0].position
			Sketchup.active_model.active_entities.add_text "1", @vertices[1].position
			Sketchup.active_model.active_entities.add_text "2", @vertices[2].position
			Sketchup.active_model.active_entities.add_text "3", @vertices[3].position
		end
		
		# Select the face in the model		
		Sketchup.active_model.selection.clear
		Sketchup.active_model.selection.add @selectedFace

		# Show the next message & the next help in the window's dialog
		Sketchup.set_status_text "BOX JOINT - Select the start edge", SB_PROMPT 
		showTab_SelectFirstEdge

		# And change the status
		@state = STATE_WAIT_FOR_SELECTING_FIRST_EDGE

		
	when STATE_WAIT_FOR_SELECTING_FIRST_EDGE
		
		# Wait for the second selection : an edge
		pick_helper = Sketchup.active_model.active_view.pick_helper
		pick_helper.do_pick x,y
		@firstEdge = pick_helper.picked_edge
		
		# Is enties selected is edge ?
		if not (@firstEdge.is_a? Sketchup::Edge)
			UI.messagebox( 'You must select an edge !')
			return
		end
		
		# Seconde selection is OK

		Sketchup.active_model.selection.clear
		Sketchup.active_model.selection.add @firstEdge

		Sketchup.set_status_text "BOX JOINT - Select the end edge", SB_PROMPT 
		showTab_SelectSecondeEdge

		# And change the status
		@state = STATE_WAIT_FOR_SELECTING_SECONDE_EDGE
		
		
	when STATE_WAIT_FOR_SELECTING_SECONDE_EDGE
	
		# Wait for the third selection : an edge
		pick_helper = Sketchup.active_model.active_view.pick_helper
		pick_helper.do_pick x,y
		@secondeEdge = pick_helper.picked_edge
		
		# Is enties selected is edge ?
		if not (@secondeEdge.is_a? Sketchup::Edge)
			UI.messagebox( 'You must select an edge !')
			return
		end
		
		# The second edge haven't common vertices with the first ?
		if ( ( @firstEdge.vertices[0] == @secondeEdge.vertices[0] ) || ( @firstEdge.vertices[0] == @secondeEdge.vertices[1] ) || ( @firstEdge.vertices[1] == @secondeEdge.vertices[0] ) || ( @firstEdge.vertices[1] == @secondeEdge.vertices[1] ) )
			UI.messagebox( 'You can''t select a continuous edge !')
			return
		end


		# Third selection is OK

		# Calculate lenght face (in millimeters)
		distance = @firstEdge.vertices[1].position.distance @secondeEdge.vertices[0].position
		distance2 = @firstEdge.vertices[0].position.distance @secondeEdge.vertices[0].position		
		if distance2 < distance
			distance = distance2
			@oppositeEdge = true
		end

		@faceLenght = distance.to_f.to_mm
		if DEBUG_MODE
			puts @faceLenght
		end

		Sketchup.active_model.selection.clear
		Sketchup.active_model.selection.add @secondeEdge
		
		Sketchup.set_status_text "BOX JOINT - Enter values", SB_PROMPT 
		showTab_EnterValues

		# And change the status
		@state = STATE_WAIT_FOR_ENTERING_VALUES
		

	end
	
end


# deactivate is called when the tool is deactivated because a different tool was selected
def	deactivate( view )
	
	# Close the dialog window
	if @dialog != nil
		@dialog.close
		@dialog = nil
	end
    
end


# onCancel is called when the user hits the escape key
def onCancel( flag, view )
	
	if DEBUG_MODE
		puts flag
		puts view
	end

	# Return to SelectMove tool
	Sketchup.send_action "selectMoveTool:"
	
	# Close the dialog window
	if @dialog != nil
		@dialog.close
		@dialog = nil
	end

end



###############################################################################
#
# webDialog box events & functions
#
###############################################################################

# Called when html file is loaded
def onDialogShow
	
	# When the html file is loaded, run the javascriptfunction setInitialeDistanceValue()
	showTab_SelectFirstFace

end


# Called when dialog box is closed
def onDialogClose

	# Return to SelectMove tool
	Sketchup.send_action "selectMoveTool:"
	
end


# Called when click on Validation button
def onValidation( message )
	
	# close the web dialog box
	@dialog.close

	# Get jointNumber & jointHeight values from the web dialog box
	@jointNumber = message.split(';')[0].to_f
	@jointHeight = message.split(';')[1].to_f
	@jointHeight = @jointHeight.mm

	# Finaly !!! Add the box joint onto the face
	addBoxJoint

	# And close dialog box
	onCancel nil, nil

end


def showTab_SelectFirstFace

	@dialog.execute_script "showTab_SelectFirstFace()"

end


def showTab_SelectFirstEdge

	@dialog.execute_script "showTab_SelectFirstEdge()"

end


def showTab_SelectSecondeEdge

	@dialog.execute_script "showTab_SelectSecondeEdge()"

end


def showTab_EnterValues

	param1 = @faceLenght.to_s
	param2 = "mm"
	param = "showTab_EnterValues( " << param1 << " , '" << param2 << "' )"

	if DEBUG_MODE
		puts param
	end

	@dialog.execute_script param

end



###############################################################################
#
# Internal functions
#
###############################################################################

def addBoxJoint
	
	if @oppositeEdge

		dx1 = ( @secondeEdge.vertices[0].position.x - @firstEdge.vertices[0].position.x ) / @jointNumber
		dx2 = ( @secondeEdge.vertices[0].position.x - @firstEdge.vertices[0].position.x ) / @jointNumber

		dy1 = ( @secondeEdge.vertices[0].position.y - @firstEdge.vertices[0].position.y ) / @jointNumber
		dy2 = ( @secondeEdge.vertices[0].position.y - @firstEdge.vertices[0].position.y ) / @jointNumber
		
		dz1 = ( @secondeEdge.vertices[0].position.z - @firstEdge.vertices[0].position.z ) / @jointNumber
		dz2 = ( @secondeEdge.vertices[0].position.z - @firstEdge.vertices[0].position.z ) / @jointNumber

		x1 = @firstEdge.vertices[0].position.x
		x2 = @firstEdge.vertices[1].position.x

		y1 = @firstEdge.vertices[0].position.y
		y2 = @firstEdge.vertices[1].position.y

		z1 = @firstEdge.vertices[0].position.z
		z2 = @firstEdge.vertices[1].position.z		

	else

		dx1 = ( @secondeEdge.vertices[1].position.x - @firstEdge.vertices[0].position.x ) / @jointNumber
		dx2 = ( @secondeEdge.vertices[0].position.x - @firstEdge.vertices[1].position.x ) / @jointNumber

		dy1 = ( @secondeEdge.vertices[1].position.y - @firstEdge.vertices[0].position.y ) / @jointNumber
		dy2 = ( @secondeEdge.vertices[0].position.y - @firstEdge.vertices[1].position.y ) / @jointNumber
		
		dz1 = ( @secondeEdge.vertices[1].position.z - @firstEdge.vertices[0].position.z ) / @jointNumber
		dz2 = ( @secondeEdge.vertices[0].position.z - @firstEdge.vertices[1].position.z ) / @jointNumber

		x1 = @firstEdge.vertices[0].position.x
		x2 = @firstEdge.vertices[1].position.x

		y1 = @firstEdge.vertices[0].position.y
		y2 = @firstEdge.vertices[1].position.y

		z1 = @firstEdge.vertices[0].position.z
		z2 = @firstEdge.vertices[1].position.z

	end

	x1 += dx1
	x2 += dx2
	y1 += dy1
	y2 += dy2
	z1 += dz1
	z2 += dz2

	n = 1

	while n < @jointNumber

		p1 = Geom::Point3d.new (x1,y1,z1)
		p4 = Geom::Point3d.new (x2,y2,z2)
		p2 = Geom::Point3d.new (x1+dx1,y1+dy1,z1+dz1)
		p3 = Geom::Point3d.new (x2+dx2,y2+dy2,z2+dz2)
		face = Sketchup.active_model.active_entities.add_face p1, p2, p3, p4
		face.pushpull -@jointHeight, false
		
		x1 += dx1 * 2
		x2 += dx2 * 2
		y1 += dy1 * 2
		y2 += dy2 * 2
		z1 += dz1 * 2
		z2 += dz2 * 2

		n+=2

	end

end



end		# end class



###############################################################################
#
# Sketechup plugin loader
#
###############################################################################

if ( not file_loaded?("net_okimi_boxjoint.rb") )
	UI.menu( "Plugins" ).add_item( "Okimi plugin - Add Box joint" ) { Sketchup.active_model.select_tool Net_Okimi_BoxJoint.new }
end
file_loaded("net_okimi_boxjoint.rb")



# Lance automatiquement la console Ruby au lancement de Sketchup, pour DEBUG
if DEBUG_MODE
	Sketchup.send_action "showRubyPanel:"
end


